
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
import java.io.*;
import javax.imageio.*;
import javax.imageio.stream.ImageInputStream;
import com.sun.image.codec.jpeg.*;

class AddressBookDemo implements ActionListener {

	JFrame appFrame;
	Container pane;
	String firstName, lastName, email;
	double salary;
	int recordNumber;
	JLabel jblFirstName, jblLastName, jblSalary, jblEmail, jblPicture;
	JTextField jtfFirstName, jtfLastName, jtfSalary, jtfEmail;
	JButton jbnSave, jbnDelete, jbnUpdate, jbnSearch, jbnClear, jbnForward,
			jbnBack, jbnExit, jbnGetPic;
	ImageIcon icon = null;
	File imgFile = null;
	PersonsDAO PDAO;
	ArrayList<PersonalInfo> personsList;
	BufferedImage bfImage = null, biProcessed = null;

	public static void main(String[] args) {
		new AddressBookDemo();
	}

	public AddressBookDemo() {

		firstName = "";
		lastName = "";
		email = "";
		salary = 0;
		recordNumber = -1;
		PDAO = new PersonsDAO();
		personsList = new ArrayList<PersonalInfo>();
		CreateGUI();
	}

	public void CreateGUI() {

		appFrame = new JFrame("Address book");

		appFrame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});

		pane = appFrame.getContentPane();
		pane.setLayout(new GridBagLayout());
		ArrangeComponents();
		appFrame.setSize(450, 300);
		appFrame.setResizable(false);
		appFrame.setVisible(true);
	}

	public void ArrangeComponents() {

		jblFirstName = new JLabel("First name");
		jtfFirstName = new JTextField(20);

		jblLastName = new JLabel("Last name");
		jtfLastName = new JTextField(25);

		jblEmail = new JLabel("Email");
		jtfEmail = new JTextField(25);

		jblSalary = new JLabel("Salary");
		jtfSalary = new JTextField(25);

		jblPicture = new JLabel("Picture");

		jblPicture.setIcon(null);
		// jblPicture.setSize(150, 150) ;

		// buttons
		jbnSearch = new JButton("Search");
		jbnExit = new JButton("Exit");
		jbnSave = new JButton("Save");
		jbnDelete = new JButton("Delete");
		jbnUpdate = new JButton("Update");
		jbnClear = new JButton("Clear");
		jbnForward = new JButton(">>");
		jbnBack = new JButton("<<");
		jbnGetPic = new JButton("Get picture");

		jbnGetPic.setMnemonic(KeyEvent.VK_P);

		GridBagConstraints c1 = new GridBagConstraints();
		c1.gridx = 0;
		c1.gridy = 0;
		c1.insets = new Insets(5, 5, 5, 5);
		pane.add(jblFirstName, c1);

		GridBagConstraints c2 = new GridBagConstraints();
		c2.gridx = 1;
		c2.gridy = 0;
		c2.gridwidth = 2;
		c2.insets = new Insets(5, 5, 5, 5);
		c2.fill = GridBagConstraints.BOTH;
		pane.add(jtfFirstName, c2);

		GridBagConstraints c3 = new GridBagConstraints();
		c3.gridx = 0;
		c3.gridy = 1;
		c3.insets = new Insets(5, 5, 5, 5);
		pane.add(jblLastName, c3);

		GridBagConstraints c4 = new GridBagConstraints();
		c4.gridx = 1;
		c4.gridy = 1;
		c4.gridwidth = 2;
		c4.insets = new Insets(5, 5, 5, 5);
		c4.fill = GridBagConstraints.BOTH;
		pane.add(jtfLastName, c4);

		GridBagConstraints c5 = new GridBagConstraints();
		c5.gridx = 0;
		c5.gridy = 2;
		c5.insets = new Insets(5, 5, 5, 5);
		pane.add(jblEmail, c5);

		GridBagConstraints c6 = new GridBagConstraints();
		c6.gridx = 1;
		c6.gridy = 2;
		c6.gridwidth = 2;
		c6.insets = new Insets(5, 5, 5, 5);
		c6.fill = GridBagConstraints.BOTH;
		pane.add(jtfEmail, c6);

		GridBagConstraints c7 = new GridBagConstraints();
		c7.gridx = 0;
		c7.gridy = 3;
		c7.insets = new Insets(5, 5, 5, 5);
		pane.add(jblSalary, c7);

		GridBagConstraints c8 = new GridBagConstraints();
		c8.gridx = 1;
		c8.gridy = 3;
		c8.gridwidth = 2;
		c8.insets = new Insets(5, 5, 5, 5);
		c8.fill = GridBagConstraints.BOTH;
		pane.add(jtfSalary, c8);

		GridBagConstraints c9 = new GridBagConstraints();
		c9.gridx = 0;
		c9.gridy = 4;
		c9.insets = new Insets(5, 5, 5, 5);
		pane.add(jbnSave, c9);

		GridBagConstraints c10 = new GridBagConstraints();
		c10.gridx = 1;
		c10.gridy = 4;
		c10.insets = new Insets(5, 5, 5, 5);
		pane.add(jbnDelete, c10);

		GridBagConstraints c11 = new GridBagConstraints();
		c11.gridx = 2;
		c11.gridy = 4;
		c11.insets = new Insets(5, 5, 5, 5);
		pane.add(jbnUpdate, c11);

		GridBagConstraints c12 = new GridBagConstraints();
		c12.gridx = 0;
		c12.gridy = 5;
		c12.insets = new Insets(5, 5, 5, 5);
		pane.add(jbnBack, c12);

		GridBagConstraints c13 = new GridBagConstraints();
		c13.gridx = 1;
		c13.gridy = 5;
		c13.insets = new Insets(5, 5, 5, 5);
		pane.add(jbnSearch, c13);

		GridBagConstraints c14 = new GridBagConstraints();
		c14.gridx = 2;
		c14.gridy = 5;
		c14.insets = new Insets(5, 5, 5, 5);
		pane.add(jbnForward, c14);

		GridBagConstraints c15 = new GridBagConstraints();
		c15.gridx = 1;
		c15.gridy = 6;
		c15.insets = new Insets(5, 5, 5, 5);
		pane.add(jbnClear, c15);

		GridBagConstraints c16 = new GridBagConstraints();
		c16.gridx = 2;
		c16.gridy = 6;
		c16.insets = new Insets(5, 5, 5, 5);
		pane.add(jbnExit, c16);

		GridBagConstraints c17 = new GridBagConstraints();
		c17.gridx = 0;
		c17.gridy = 6;
		c17.insets = new Insets(5, 5, 5, 5);
		pane.add(jbnGetPic, c17);

		GridBagConstraints c18 = new GridBagConstraints();
		c18.gridx = 3;
		c18.gridy = 0;
		c18.gridwidth = 5;
		c18.gridheight = 5;
		// c18.fill= GridBagConstraints.VERTICAL;
		c18.insets = new Insets(5, 5, 5, 5);
		pane.add(jblPicture, c18);

		jbnSearch.addActionListener(this);
		jbnExit.addActionListener(this);
		jbnSave.addActionListener(this);
		jbnDelete.addActionListener(this);
		jbnUpdate.addActionListener(this);
		jbnBack.addActionListener(this);
		jbnForward.addActionListener(this);
		jbnClear.addActionListener(this);
		jbnGetPic.addActionListener(this);
	}

	public void actionPerformed(ActionEvent e) {

		if (e.getSource() == jbnExit) {
			System.exit(0);
		} else if (e.getSource() == jbnSearch) {
			SearchPerson();
		} else if (e.getSource() == jbnClear) {
			Clear();
		} else if (e.getSource() == jbnForward) {
			Forward();
		} else if (e.getSource() == jbnBack) {
			Back();
		} else if (e.getSource() == jbnUpdate) {
			updatePerson();
		} else if (e.getSource() == jbnSave) {
			savePerson();
		} else if (e.getSource() == jbnDelete) {
			deletePerson();
		} else if (e.getSource() == jbnGetPic) {
			ChooseImage();
		}
	}

	public void ChooseImage() {
		JFileChooser fileChs = new JFileChooser();
		fileChs.setDialogTitle("Choose file for loading");
		fileChs.setFileSelectionMode(JFileChooser.FILES_ONLY);
		fileChs.setFileFilter(new TextFileFilter());
		int res = fileChs.showOpenDialog(appFrame);
		if (res == JFileChooser.APPROVE_OPTION) {
			imgFile = fileChs.getSelectedFile();

			try {
				bfImage = ImageIO.read(imgFile);
			} catch (IOException e) {
			}
			CreatePictureIcon(bfImage, "");
			jblPicture.setIcon(icon);
			jblPicture.setText("");
			// MyFrame.this.getPicturePanel().setImageFile(fileChs.getSelectedFile());
			// BufferedImage im = MyFrame.this.getPicturePanel().getImage();
			// MyFrame.this.setSize(im.getWidth(),im.getHeight());

		}

	}

	protected void CreatePictureIcon(BufferedImage inImage, String description) {
		int maxDim = 150;
		// ImageIcon icon = null;
		// inImage = null;
		// try {
		// inImage = ImageIO.read(file);
		// } catch (IOException e) {
		// }

		try {
			// Image inImage = icon.getImage();

			double scale = (double) maxDim / (double) inImage.getHeight(null);
			if (inImage.getWidth(null) > inImage.getHeight(null)) {
				scale = (double) maxDim / (double) inImage.getWidth(null);
			}

			int scaledW = (int) (scale * inImage.getWidth(null));
			int scaledH = (int) (scale * inImage.getHeight(null));

			BufferedImage outImage = new BufferedImage(scaledW, scaledH,
					BufferedImage.TYPE_INT_RGB);

			AffineTransform tx = new AffineTransform();

			if (scale < 1.0d) {
				tx.scale(scale, scale);
			}

			Graphics2D g2d = outImage.createGraphics();
			g2d.drawImage(inImage, tx, null);
			g2d.dispose();

			biProcessed = outImage;
			icon = new ImageIcon(outImage);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected void CreatePictureIcon(Image inImage, String description) {
		int maxDim = 150;
		// ImageIcon icon = null;
		// inImage = null;
		// try {
		// inImage = ImageIO.read(file);
		// } catch (IOException e) {
		// }

		try {
			// Image inImage = icon.getImage();

			double scale = (double) maxDim / (double) inImage.getHeight(null);
			if (inImage.getWidth(null) > inImage.getHeight(null)) {
				scale = (double) maxDim / (double) inImage.getWidth(null);
			}

			int scaledW = (int) (scale * inImage.getWidth(null));
			int scaledH = (int) (scale * inImage.getHeight(null));

			BufferedImage outImage = new BufferedImage(scaledW, scaledH,
					BufferedImage.TYPE_INT_RGB);

			AffineTransform tx = new AffineTransform();

			if (scale < 1.0d) {
				tx.scale(scale, scale);
			}

			Graphics2D g2d = outImage.createGraphics();
			g2d.drawImage(inImage, tx, null);
			g2d.dispose();

			biProcessed = outImage;
			icon = new ImageIcon(outImage);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void SearchPerson() {
		lastName = jtfLastName.getText();
		recordNumber = 0;
		personsList.clear();
		lastName = lastName.trim();
		if (lastName.equals("")) {
			JOptionPane.showMessageDialog(null,
					"Please enter 'last name' field");
		} else {
			personsList = PDAO.searchPerson(lastName);

			if (personsList.size() == 0) {
				JOptionPane.showMessageDialog(null, "No records found");
				Clear();
			} else {
				PersonalInfo person = personsList.get(recordNumber);

				jtfFirstName.setText(person.getFirstName());
				jtfLastName.setText(person.getLastName());
				jtfEmail.setText(person.getEmail());
				jtfSalary.setText("" + person.getSalary());

				/*
				 * try { BufferedInputStream is = new BufferedInputStream
				 * (person.getIsImage()); bfImage = ImageIO.read(is); } catch
				 * (IOException e) {
				 * 
				 * Image image = person.getImage(); if (image != null){
				 * CreatePictureIcon(image, ""); jblPicture.setIcon(icon);
				 * jblPicture.setText(""); } }
				 */
				icon = person.getIcon();
				jblPicture.setIcon(icon);
				jblPicture.setText("");
			}
		}
	}

	public void updatePerson() {
		if (recordNumber < 0 || personsList.size() == 0) {
			JOptionPane.showMessageDialog(null, "Please, choose any person");
			return;
		}
		int rowCount;
		PersonalInfo person = personsList.get(recordNumber);

		ByteArrayOutputStream os = new ByteArrayOutputStream();
		try {
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
			encoder.encode(biProcessed);
		} catch (Exception ex) {
			System.err.println("Error occured: " + ex.getMessage());
		}
		byte[] byteArray = os.toByteArray();

		rowCount = PDAO.updatePerson(person.getId(), jtfFirstName.getText(),
				jtfLastName.getText(), jtfSalary.getText(), jtfEmail.getText(),
				byteArray);
		person.setIcon(icon);
		personsList.set(recordNumber, person);
		if (rowCount > 0) {
			JOptionPane
					.showMessageDialog(null, "Record has successful updated");
		}
	}

	public void savePerson() {
		firstName = jtfFirstName.getText();
		lastName = jtfLastName.getText();
		if (firstName.equals("") || lastName.equals("")) {
			JOptionPane.showMessageDialog(null,
					"Please, fill in 'first name' and 'last name' fields");
			return;
		}
		int rowCount;
		rowCount = PDAO.savePerson(firstName, lastName, jtfSalary.getText(),
				jtfEmail.getText());
		if (rowCount > 0) {
			JOptionPane.showMessageDialog(null,
					"Record has successfully created");
		}
	}

	public void deletePerson() {

		int selection = JOptionPane.showConfirmDialog(null, "Are you sure?",
				"Deleting record", JOptionPane.YES_NO_OPTION,
				JOptionPane.QUESTION_MESSAGE);
		if (selection == JOptionPane.NO_OPTION) {
			return;
		}

		if (recordNumber < 0 || personsList.size() == 0) {
			JOptionPane.showMessageDialog(null, "Please, choose any person");
			return;
		}
		int rowCount;
		PersonalInfo person = personsList.get(recordNumber);
		rowCount = PDAO.deletePerson(person.getId());
		if (rowCount > 0) {
			JOptionPane.showMessageDialog(null,
					"Record has successfully deleted");
			Clear();
		}
	}

	public void Forward() {
		recordNumber++;
		int personSize = personsList.size();
		if (recordNumber >= personSize) {
			recordNumber--;
			jbnForward.setEnabled(false);
			jbnBack.setEnabled(true);
			JOptionPane.showMessageDialog(null,
					"You have reached end of the list");
		} else {
			if (personSize == 0) {
				JOptionPane.showMessageDialog(null, "No records found");
				Clear();
			} else {
				jbnBack.setEnabled(true);
				PersonalInfo person = personsList.get(recordNumber);

				jtfFirstName.setText(person.getFirstName());
				jtfLastName.setText(person.getLastName());
				jtfEmail.setText(person.getEmail());
				jtfSalary.setText("" + person.getSalary());

				icon = person.getIcon();
				jblPicture.setIcon(icon);
				if (icon == null) {
					jblPicture.setText("Picture");
				} else {
					jblPicture.setText("");
				}

			}
		}
	}

	public void Back() {
		recordNumber--;
		int personSize = personsList.size();
		if (recordNumber < 0) {
			recordNumber++;
			jbnBack.setEnabled(false);
			jbnForward.setEnabled(true);
			JOptionPane.showMessageDialog(null,
					"You have reached begining of the list");
		} else {
			if (personSize == 0) {
				JOptionPane.showMessageDialog(null, "No records found");
				Clear();
			} else {
				jbnForward.setEnabled(true);
				PersonalInfo person = personsList.get(recordNumber);

				jtfFirstName.setText(person.getFirstName());
				jtfLastName.setText(person.getLastName());
				jtfEmail.setText(person.getEmail());
				jtfSalary.setText("" + person.getSalary());

				icon = person.getIcon();
				jblPicture.setIcon(icon);
				if (icon == null) {
					jblPicture.setText("Picture");
				} else {
					jblPicture.setText("");
				}
			}
		}
	}

	public void Clear() {
		recordNumber = -1;
		personsList.clear();
		jtfFirstName.setText("");
		jtfLastName.setText("");
		jtfEmail.setText("");
		jtfSalary.setText("");
		jblPicture.setIcon(null);
		jblPicture.setText("Picture");

		jbnForward.setEnabled(true);
		jbnBack.setEnabled(true);
	}

}